
package com.sawgdev.android.bokuiki.activity;

import com.sawgdev.android.bokuiki.R;
import com.sawgdev.android.bokuiki.bean.BeanMailSetting;
import com.sawgdev.android.bokuiki.common.mail.Encipherment;
import com.sawgdev.android.bokuiki.common.mail.Mail;

import org.apache.commons.lang3.StringUtils;

import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.RadioGroup;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

/**
 * <pre>
 * メール設定画面のActivityです。
 * </pre>
 */
public class ActMailSetting extends Activity {

    /** メール設定情報を保存するファイル名 */
    private static final String DB_NAME = "mail_db";

    private RadioButton rbtGmail;

    private RadioGroup rgpFromAddress;

    /** メールアドレス */
    private EditText etxMailAddress;

    /** パスワード */
    private EditText etxMailPassword;

    /** STMP名 */
    private EditText etxSmtpName;

    /** ホスト名 */
    private EditText etxHostName;

    /** ポート番号 */
    private EditText etxPortNo;

    /** SMTPチェックボックス */
    private CheckBox chbSmtpAuth;

    /** TLSチェックボックス */
    private CheckBox chbTls;

    /** その他メールアドレス設定のリニアレイアウト */
    private LinearLayout lltOtherMailSetting;

    /** 設定ボタン */
    private Button btnSetting;

    /** キャンセルボタン */
    private Button btnCancel;

    /** ラジオボタン変更時のリスナー */
    private RadioGroup.OnCheckedChangeListener changeRgpFromAddress = new RadioGroup.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(RadioGroup group, int checkedId) {
            // 「GMail」か「その他のメールアドレス」で表示を切り替える
            if (rbtGmail.isChecked()) {
                lltOtherMailSetting.setVisibility(View.GONE);
            } else {
                lltOtherMailSetting.setVisibility(View.VISIBLE);
            }
        }
    };

    private View.OnClickListener clickBtnSetting = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            try {
                if (validate()) {
                    setData();
                    finish();
                }
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    };

    private View.OnClickListener clickBtnCancel = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            finish();
        }
    };

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.mail_setting);
    }

    @Override
    protected void onResume() {
        super.onResume();

        rbtGmail = (RadioButton) findViewById(R.id.rbt_gmail);

        // GMailアドレスを取得し、ラジオボタンに表示する
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(getString(R.string.radio_gmail));
        stringBuilder.append(" ( ");
        stringBuilder.append(Mail.getGmailAddress(this));
        stringBuilder.append(" ) ");
        rbtGmail.setText(stringBuilder);

        lltOtherMailSetting = (LinearLayout) findViewById(R.id.llt_other_mail_setting);

        rgpFromAddress = (RadioGroup) findViewById(R.id.rgp_from_address);
        rgpFromAddress.setOnCheckedChangeListener(changeRgpFromAddress);
        if (getData().getMailType() == 1) {
            rgpFromAddress.check(R.id.rbt_gmail);
        } else {
            rgpFromAddress.check(R.id.rbt_other_address);
        }

        // 「GMail」か「その他のメールアドレス」で表示を切り替える
        if (rbtGmail.isChecked()) {
            lltOtherMailSetting.setVisibility(View.GONE);
        } else {
            lltOtherMailSetting.setVisibility(View.VISIBLE);
        }

        // 各種設定情報を取得し、表示する
        etxMailAddress = (EditText) findViewById(R.id.mail_address);
        etxMailAddress.setText(getData().getMailAddress());
        etxMailPassword = (EditText) findViewById(R.id.mail_password);
        etxSmtpName = (EditText) findViewById(R.id.smtp_name);
        etxSmtpName.setText(getData().getSmtpName());
        etxHostName = (EditText) findViewById(R.id.host_name);
        etxHostName.setText(getData().getHostName());
        etxPortNo = (EditText) findViewById(R.id.port_no);
        etxPortNo.setText(getData().getPortNo());
        chbSmtpAuth = (CheckBox) findViewById(R.id.smtp_auth);
        if (getData().getSmtpAuth() == "true") {
            chbSmtpAuth.setChecked(true);
        } else {
            chbSmtpAuth.setChecked(false);
        }
        chbTls = (CheckBox) findViewById(R.id.tls);
        if (getData().getTls() == "true") {
            chbTls.setChecked(true);
        } else {
            chbTls.setChecked(false);
        }

        btnSetting = (Button) findViewById(R.id.button_setting);
        btnCancel = (Button) findViewById(R.id.button_cancel);

        btnSetting.setOnClickListener(clickBtnSetting);
        btnCancel.setOnClickListener(clickBtnCancel);
    }

    /**
     * <pre>
     * メール設定情報をSharedPreferencesに保存します
     * </pre>
     */
    private void setData() {
        SharedPreferences sp = getSharedPreferences(DB_NAME, Context.MODE_PRIVATE);
        Editor editor = sp.edit();
        Encipherment encipherment = new Encipherment();
        try {
            editor.putString("MailPassword", encipherment.encrypt(etxMailPassword.getText().toString()));
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        }
        if (rgpFromAddress.getCheckedRadioButtonId() == R.id.rbt_gmail) {
            editor.putInt("MailType", 1);
        } else {
            editor.putInt("MailType", 2);
            editor.putString("MailAddress", etxMailAddress.getText().toString());
            editor.putString("SmtpName", etxSmtpName.getText().toString());
            editor.putString("HostName", etxHostName.getText().toString());
            editor.putString("PortNo", etxPortNo.getText().toString());
            if (chbSmtpAuth.isChecked()) {
                editor.putString("SmtpAuth", "true");
            } else {
                editor.putString("SmtpAuth", "false");
            }
            if (chbTls.isChecked()) {
                editor.putString("Tls", "true");
            } else {
                editor.putString("Tls", "false");
            }
        }
        editor.commit();
    }

    /**
     * <pre>
     * メール設定情報をSharedPreferencesから取得します
     * </pre>
     *
     * @return メール設定情報
     */
    private BeanMailSetting getData() {
        SharedPreferences sp = getSharedPreferences(DB_NAME, Context.MODE_PRIVATE);

        BeanMailSetting beanMailSetting = new BeanMailSetting();
        beanMailSetting.setMailType(sp.getInt("MailType", 1));
        beanMailSetting.setMailAddress(sp.getString("MailAddress", ""));
        Encipherment encipherment = new Encipherment();
        String password = sp.getString("MailPassword", "");
        if (password != "" || password.length() > 0) {
            try {
                beanMailSetting.setMailPassword(encipherment.decrypt(sp.getString("MailPassword",
                        "")));
            } catch (InvalidKeyException e) {
                e.printStackTrace();
            } catch (IllegalBlockSizeException e) {
                e.printStackTrace();
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            } catch (BadPaddingException e) {
                e.printStackTrace();
            } catch (NoSuchPaddingException e) {
                e.printStackTrace();
            }
        }
        beanMailSetting.setSmtpName(sp.getString("SmtpName", ""));
        beanMailSetting.setHostName(sp.getString("HostName", ""));
        beanMailSetting.setPortNo(sp.getString("PortNo", ""));
        beanMailSetting.setSmtpAuth(sp.getString("SmtpAuth", "true"));
        beanMailSetting.setTls(sp.getString("Tls", "true"));
        return beanMailSetting;
    }

    /**
     * <pre>
     * 入力チェックをします。
     * </pre>
     *
     * @return true:OK false:NG
     * @throws IllegalAccessException
     * @throws IllegalArgumentException
     */
    private boolean validate() throws IllegalArgumentException, IllegalAccessException {
        boolean result = true;

        // EditTextのエラー表示を初期化
        for (Field field : this.getClass().getDeclaredFields()) {
            if (StringUtils.startsWith(field.getName(), "edt")) {
                field.setAccessible(true);
                EditText edt = (EditText) field.get(this);
                edt.setError(null);
            }
        }

        // パスワードチェック
        if (!StringUtils.isNotEmpty(etxMailPassword.getText().toString())) {
            result = false;
            etxMailPassword.setError("パスワードを入力してください。");
        }

        if (rgpFromAddress.getCheckedRadioButtonId() != R.id.rbt_gmail) {
            if (!StringUtils.isNotEmpty(etxMailAddress.getText().toString())) {
                result = false;
                etxMailAddress.setError("メールアドレスを入力してください。");
            }
            if (!StringUtils.isNotEmpty(etxSmtpName.getText().toString())) {
                result = false;
                etxSmtpName.setError("SMTP名を入力してください。");
            }
            if (!StringUtils.isNotEmpty(etxHostName.getText().toString())) {
                result = false;
                etxHostName.setError("ホスト名を入力してください。");
            }
            if (!StringUtils.isNotEmpty(etxPortNo.getText().toString())) {
                result = false;
                etxPortNo.setError("ポート番号を入力してください。");
            }
        }

        return result;
    }
}
